import os
import tempfile
from moviepy.editor import AudioFileClip
from pydub import AudioSegment


class AudioMerger:
    def __init__(self, input_file_items, output_file_path, queue):
        self.input_file_items = input_file_items
        self.output_file_path = output_file_path
        self.queue = queue
        self.input_files = self.process_before_merge()


    def process_before_merge(self):
        """处理输入的文件，按照时间截取和音量调整"""
        processed_files = []
        for item in self.input_file_items:
            file = item["file"]
            duration = item["duration"]
            volume = item["volume"]

            # 处理音频文件
            if file.endswith(".mp3") or file.endswith(".wav") or file.endswith(".flac"):
                processed_file = self.process_audio(file, duration, volume)

            # 处理视频文件
            elif (
                file.endswith(".mp4") or file.endswith(".avi") or file.endswith(".mkv")
            ):
                processed_file = self.process_video(file, duration, volume)

            processed_files.append(processed_file)

        return processed_files

    def process_audio(self, audio_path, duration, volume):
        """处理音频文件：截取指定时长并调整音量"""
        audio = AudioSegment.from_file(audio_path)
        audio = audio[: duration * 1000]  # 截取指定时长（毫秒）
        audio = audio + (volume * 10)  # 根据音量调整，音量增益单位dB
        processed_audio_path = os.path.splitext(audio_path)[0] + "_processed.wav"
        audio.export(processed_audio_path, format="wav")
        return processed_audio_path

    def process_video(self, video_path, duration, volume):
        """从视频中提取音频并处理：截取指定时长并调整音量"""
        audio_path = os.path.splitext(video_path)[0] + "_audio.wav"
        self.extract_audio_from_video(video_path, audio_path)  # 提取音频

        audio = AudioSegment.from_wav(audio_path)
        audio = audio[: duration * 1000]  # 截取指定时长（毫秒）
        audio = audio + (volume * 10)  # 根据音量调整，音量增益单位dB
        processed_audio_path = os.path.splitext(audio_path)[0] + "_processed.wav"
        audio.export(processed_audio_path, format="wav")
        return processed_audio_path

    def extract_audio_from_video(self, video_path, audio_path):
        """从视频中提取音频并保存为音频文件"""
        audio_clip = AudioFileClip(video_path)  # 使用 AudioFileClip 提取音频
        audio_clip.write_audiofile(audio_path)
        audio_clip.close()

    def convert_to_wav(self, audio_path):
        """将音频文件转换为 WAV 格式，处理不同的音频格式"""
        audio = AudioSegment.from_file(audio_path)
        wav_path = os.path.splitext(audio_path)[0] + ".wav"
        audio.export(wav_path, format="wav")
        return wav_path

    def get_max_duration(self, audio_files):
        """计算所有音频文件的最大时长"""
        max_duration = 0
        for audio_file in audio_files:
            self.queue.put(1)
            audio = AudioSegment.from_wav(audio_file)
            max_duration = max(max_duration, len(audio))
        return max_duration

    def merge_audio_files(self, audio_files, max_duration):
        """将多个音频文件叠加在一起（从第0秒开始）"""
        # 加载第一个音频文件
        base_audio = AudioSegment.from_wav(audio_files[0])

        for audio_file in audio_files[1:]:
            self.queue.put(1)
            next_audio = AudioSegment.from_wav(audio_file)
            # 计算当前音频需要的位置
            base_audio = base_audio.overlay(next_audio, position=0)

        # 确保合并的音频长度不短于最长音频的长度
        if len(base_audio) < max_duration:
            silence_duration = max_duration - len(base_audio)
            silence = AudioSegment.silent(duration=silence_duration)
            base_audio += silence

        return base_audio

    def save_merged_audio(self, merged_audio, output_path):
        """保存合并后的音频文件"""
        merged_audio.export(output_path, format="mp3")
        print(f"合并后的音频已保存至: {output_path}")
        self.queue.put(1)

    def merge_audio(self):
        audio_files = []
        output_file = tempfile.mktemp(suffix=".mp3", dir=self.output_file_path)

        # 获取已处理的音频文件列表
        for file in self.input_files:
            self.queue.put(1)
            audio_files.append(file)

        # 计算所有音频文件的最大时长
        max_duration = self.get_max_duration(audio_files)

        # 合并音频文件
        merged_audio = self.merge_audio_files(audio_files, max_duration)

        # 保存合并后的音频
        self.save_merged_audio(merged_audio, output_file)

        # 清理临时的音频文件
        for audio_file in audio_files:
            self.queue.put(1)
            if os.path.exists(audio_file):
                os.remove(audio_file)

